package cn.gzmli.dtt.common.utils;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @Author jiangdw
 * @CreateDate: 2019/9/11 10:01
 * @Description 生成流水号工具类
 *
 * <p>
 *   流水号长度为21位，由3部分组成
 *   1: 时间, 格式yyMMddhhmmss,长度为12位
 *   2: 两位用来区分不同程序的数字
 *   3： 7位循序流水号
 * </p>
 *
 **/
public class SequenceGenerator {
	/**
	 * 用来区别不同程序的一个数字(不超过两位数).
	 * 程序启动多个实例时，通过设置不同的salt来保证各个程序流水号不会重复.
	 * 
	 */
	private int salt;
	
	/**
	 * 循环流水号.
	 * 
	 * 在1-90000之间循环，如果程序每秒要生成的流水号超过或接近9000个，可以通过启动多个程序实例来分担压力，保证流水号不会重复.
	 * 
	 * 目前暂时还没有会出现这么大的压力的程序.
	 * 
	 */
	private AtomicInteger seq = new AtomicInteger(1);
	
	/** 同步锁. */
	 private byte[] lock = new byte[0]; // 特殊的instance变量

	/**
	 * 格式化日期的SimpleDateFormat.
	 */
	private SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");

    public SequenceGenerator() {}

	/**
	 * 取得流水号.
	 * 
	 * @return 流水号
	 */
	public synchronized String get(int salt) {
        this.salt = salt;
		String now = format.format(new Date());
		String rodmnum=getNumCode();
		int cur = 0;
		synchronized (lock) {
		// 原子整型的incrementAndGet方法，以原子方式将当前值加 1，返回更新的值
			cur = seq.incrementAndGet();
			if (cur >= 9000) {
				seq.set(0);
			}
		}
	// 时间阀+领域编号+原子整数码
		return String.format("%s%02d%04d%s", now, salt, cur,rodmnum);
	}
	
	public synchronized String getLoginId() {
		String now = format.format(new Date());
		String rodmnum=getNumCode();
		int cur = 0;
		synchronized (lock) {
		// 原子整型的incrementAndGet方法，以原子方式将当前值加 1，返回更新的值
			cur = seq.incrementAndGet();
			if (cur >= 900) {
				seq.set(0);
			}
		}
	// 时间阀+领域编号+原子整数码
		return String.format("%s%03d", now, cur);
	}

	public static void main(String args[]){
		System.out.println(new SequenceGenerator().get(3));
	}


    public static String getNumCode(){
        String[] beforeShuffle = new String[] {"2","3","4","5","6","7",
                "8","9","0","1"};
        List list = Arrays.asList(beforeShuffle);
        Collections.shuffle(list);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i));
        }
        String afterShuffle = sb.toString();
        String result = afterShuffle.substring(5, 9);
        return result;
    }
}
